from sqlalchemy import Column, String, Text, Integer
from sqlalchemy.ext.asyncio import AsyncSession

from commons.crud_base import CRUDDao, CRUDService
from commons.crud_controller import CRUDController
from commons.eo_vo import CBase, TBase, IDBase, sqlalchemy_to_pydantic, PageQueryModel
from config.database import Base
from module_admin.annotation.pydantic_annotation import as_query, as_form

from fastapi import Depends

from commons.crud_base import CRUDService
from commons.eo_vo import PageQueryModel
from config.get_db import get_db
from module_admin.aspect.interface_auth import CheckUserInterfaceAuth
from utils.log_util import *
from utils.response_util import *


class Blog(Base, CBase, TBase, IDBase):
    title = Column(String(128), nullable=False, comment='标题')
    tags = Column(String(128), nullable=True, default='', comment='标签')
    content = Column(Text, nullable=True, default='', comment='内容')
    stars = Column(Integer, nullable=True, default=0, comment='赞')


BlogModel, BlogQueryModel = sqlalchemy_to_pydantic(Blog)


@as_query
@as_form
class BlogPageQueryModel(BlogQueryModel, PageQueryModel):
    pass


class BlogDao(CRUDDao[Blog, BlogModel, BlogPageQueryModel]):
    mo = Blog


class BlogService(CRUDService[Blog, BlogModel, BlogPageQueryModel]):
    dao = BlogDao
    vo = BlogModel
    mapping_dict: dict = {}
    msg: str = 'Blog'

    @classmethod
    async def _check_edit_dup(cls, db: AsyncSession, vo: BlogModel, db_vo: BlogModel):
        if vo.title != db_vo.title:
            ex = await cls.dao.get_detail_by_vo(db, BlogModel(title=vo.title))
            if ex:
                return True
        return False


blogController = CRUDController("/blog", "blog", "Blog", BlogService, BlogModel, BlogPageQueryModel)


@blogController.put("/star/{id}", response_model=BlogModel, dependencies=[Depends(CheckUserInterfaceAuth(f'blog:r'))])
async def star_blog(id: int, db: AsyncSession = Depends(get_db)):
    try:
        result = await BlogService.detail(db, id)
        result.stars += 1
        await BlogService.edit(db, result)
        logger.info(f'Star成功')
        return ResponseUtil.success(data=result) if result else ResponseUtil.failure(msg='未查询到数据')
    except Exception as e:
        logger.exception(e)
        return ResponseUtil.error(msg=str(e))
